This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
#values needed 
K= 1.38064852*(10)^-23 #m2 kg/ s2 K boltzmann constant
mu= 1.126*(10)^-3 #kg/m s dynamic viscosity in 18C
v= 1.099*(10)^-6 #m2/s kinematic viscosity in 18C
Reh_calc= 2.3E-6 #in m radius Ehux
Reh_naked= 1.8E-6 #in m radius Ehux
Rehv= 90*(10)^-9 #in m radius virus
Temp = 18+273.15 #temp in kelvin, here assuming 18C
Den_OcM = 1.05 #g/cm3 density organic cell matter
Den_CH2O= 1.025 #g/cm3 density seawater at 18C
hostnum <- (10)^3
virnum <- (10)^4
require (ggplot2)
require(plotly)
require(grid)
require(ggthemes)
require (dplyr)
require(plyr)
source ("theme_Publication.R")
source("resizewin.R")
resize.win(12,9)
Error in dev.off() : cannot shut down device 1 (the null device)

for Brownian motion

#Brownian motion (BM)
#1. make a data frame
BM <- data.frame (group= c("naked", "calcified"), rad= c(1.8E-6, 2.3E-6)) 
#2. calculate beta (beta)
BM$beta_s <- (2*(K*(10)^4)*Temp*(((BM$rad+Rehv)*100)^2))/((3*mu*10)*(BM$rad*Rehv*1e4)) #m3/s
BM$beta_d <- BM$beta_s*86400 #to cm3/day
# go back to this later
#3. calculate encounters (E)
BM$E <- BM$beta_d*hostnum
BM$E_HV <- BM$beta_d*virnum*hostnum
BM

Differential settling (DS)

#Differential settling (DS)
#1. read in PIC data
library(readr) #always use readr not baseR
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
PIC <- read_csv("Postdoc-R/CSV Files/PIC.csv")
Parsed with column specification:
cols(
  Strain = col_character(),
  Replicate = col_integer(),
  TC = col_double(),
  AC = col_double(),
  Cellcount = col_double()
)
PIC$Strain <- as.factor(PIC$Strain)
PIC$Replicate <- as.factor(PIC$Replicate)
#certain changes in data.table API made calculating inside the list data.table to not work
#2. calculate PIC
PIC$PIC <- PIC$TC-PIC$AC
PIC$PICpercell <- (PIC$PIC/PIC$Cellcount)*(10)^-3#in g
PIC$PICpercellpg <- PIC$PICpercell*1e12
ggplotly(ggplot(data=PIC, aes(x=Strain, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2) +theme_Publication())
#3. calculate density of cells (den)
PIC <- mutate(PIC, group = ifelse(PICpercellpg < 4 , "naked", "calcified"))
ggplotly(ggplot(data=PIC, aes(x=group, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2, aes(color=Strain))+
           theme_Publication())
plotly.js does not (yet) support horizontal legend items 
You can track progress here: 
https://github.com/plotly/plotly.js/issues/53 

PIC <- mutate(PIC, rad = ifelse(group == "naked" ,  1.8E-6,  2.3E-6)) #in m
PIC$volume <- (4/3)*pi*(PIC$rad*100)^3 #in cm3
PIC$Den_cell <- PIC$PICpercell/PIC$volume #g/cm3
PIC$Den_celltotal <- PIC$Den_cell+Den_OcM
ggplotly(ggplot(data=PIC, aes(x=Strain, y=Den_celltotal, color=group)) + geom_boxplot()+geom_point(size=2) 
         +theme_Publication())
plotly.js does not (yet) support horizontal legend items 
You can track progress here: 
https://github.com/plotly/plotly.js/issues/53 

#some strains that are "naked" have PIC<2. I chose to ignore this since in the lm model I do not use
#strain as a factor, rather data is treated as a whole (e.g., no grouping)
#4. calculate sinking velocity of cells
PIC$SinkVel <- ((2*((PIC$rad*100)^2)*(981)*(PIC$Den_celltotal-Den_CH2O))/(9*(mu*10)))*864 #meter per day
#g is converted to per day, 864 is the one that converts cm/s to m/day
#plot sinking velocity vs calcification
ggplot(data=PIC, aes(x=PICpercellpg, y=SinkVel, color=Strain, shape=group)) + geom_point(size=5)+theme_Publication()+
    labs(y = expression("Sinking velocity"~("m"~day^-1)), x = expression("PIC"~cell^-1)) +
    scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

#5. calculate sinkvel of viruses
Den_virus <- 1.09 #data from Ben D. fresh EhV-207 density. old density of EhV-207 is 1.19
Ehv_SinkVel <- ((2*((Rehv*100)^2)*(981)*(Den_virus-Den_CH2O))/(9*(mu*10)))*864  #equals to 0
#6. calculate beta kernels
PIC$beta_s <- pi*(((PIC$rad+Rehv)*100)^2)*(abs((PIC$SinkVel-Ehv_SinkVel)/864)) #in encounters cm3/s
PIC$beta_d <- PIC$beta_s*86400 #in cm3/day
Sinkvelbeta.plot<- ggplot(data=PIC, aes(x=SinkVel, y=beta_d, color=Strain, shape=group)) + geom_point(size=5)+
  theme_Publication()+
  labs(x = expression("Sinking velocity"~("m"~day^-1)), y = expression(beta~("Encounters" ~ cm^3~day^-1))) +
 scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")
Sinkvelbeta.plot #change ticks

ggplotly(Sinkvelbeta.plot)
geom_GeomLogticks() has yet to be implemented in plotly.
  If you'd like to see this geom implemented,
  Please open an issue with your example code at
  https://github.com/ropensci/plotly/issuesplotly.js does not (yet) support horizontal legend items 
You can track progress here: 
https://github.com/plotly/plotly.js/issues/53 

ggplotly(ggplot(data=PIC, aes(x=Strain, y=SinkVel)) + geom_boxplot()+theme_Publication())

ggplot(data=PIC, aes(x=PICpercellpg, y=beta_d, color=Strain)) + geom_point(size=5)+theme_Publication()+
  labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC"~cell^-1))  +
scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

#7. calculate beta and encounters
#beta are in cells cm3/ day then encounters are to cells/cm3 day
PIC$E_DS_HV <- (PIC$beta_d*virnum*hostnum)  #E calculated with Virus and Host (10:1 MOI)
PIC$E_DS_V <- (PIC$beta_d*virnum) #E calculated with Virus
#8. calculate for lith parameters
lithvol <- 3*1e-12 #in cm3, from CJ's paper
PIC$perlith <- PIC$PICpercell/20 #in g, assuming 20 liths attached
PIC$perlithpg <- PIC$perlith*1e12 #in pg
PIC$Denlith <- (PIC$perlith/lithvol) + Den_OcM #in g/cm3, with organic matter attached
rad_lith <- 2E-6 #in m radius
PIC$SinkVel_lith <- ((2*((rad_lith*100)^2)*(981)*(PIC$Denlith-Den_CH2O))/(9*(mu*10)))*864 #meter per day
PIC$beta_s_lith <- pi*(((rad_lith+Rehv)*100)^2)*(abs((PIC$SinkVel_lith-Ehv_SinkVel)/864)) #in encounters cm3/s
PIC$beta_d_lith <- PIC$beta_s_lith*86400 #in cm3/day
ggplot(data=PIC, aes(x=perlithpg, y=SinkVel_lith, color=Strain, shape=group)) + geom_point(size=5)+theme_Publication()+
  labs(y = expression("Sinking velocity"~("m"~day^-1)), x = expression("PIC"~lith^-1)) 

PIC$Elith_DS_HV <- (PIC$beta_d_lith*virnum*hostnum)  #E calculated with Virus and Host (10:1 MOI)
PIC$Elith_DS_V <- (PIC$beta_d_lith*virnum) #E calculated with Virus
require (dplyr)
PIC$group2 <- case_when(
  PIC$PICpercellpg <2  ~ "naked_bouyant",
  PIC$PICpercellpg >2 & PIC$PICpercellpg < 4 ~ "naked/calcified uncertain",
  PIC$PICpercellpg >4 & PIC$PICpercellpg < 10 ~ "moderately calcified",
  PIC$PICpercellpg >10 ~ "strongly calcified", 
  TRUE ~ as.character(PIC$PICpercellpg)
)
breaks <- 10^(-10:10)
ggplot(data=PIC, aes(x=SinkVel, y=E_DS_HV, color=Strain, shape=group)) + geom_point(size=5)+theme_Publication()+
 scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

ggplot(data=PIC, aes(x=SinkVel, y=E_DS_V, color=Strain, shape=group)) + geom_point(size=5)+theme_Publication()+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

ggplot(data=PIC, aes(x=SinkVel_lith, y=Elith_DS_V, color=Strain, shape=group)) + geom_point(size=5) + 
  theme_Publication() + scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=3),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

summary_DS <- ddply(PIC, .(Strain), summarize,  PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg), 
                    Den_celltotal = mean (Den_celltotal),
                    SinkVel=mean(SinkVel),beta_d=mean(beta_d), E_DS_V= mean(E_DS_V), E_DS_HV=mean(E_DS_HV),
                    SinkVel_lith=mean (SinkVel_lith), beta_d_lith=mean (beta_d_lith), Elith_DS_HV=mean (Elith_DS_HV),
                    Elith_DS_V=mean (Elith_DS_V))
summary_DS_bygroup <- ddply(PIC, .(group2), summarize,  PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg), 
                            Den_celltotal = mean (Den_celltotal),
                            SinkVel=mean(SinkVel),beta_d=mean(beta_d), E_DS_V= mean(E_DS_V), E_DS_HV=mean(E_DS_HV), 
                            SinkVel_lith=mean (SinkVel_lith), beta_d_lith=mean (beta_d_lith), 
                            Elith_DS_HV=mean (Elith_DS_HV), Elith_DS_V=mean (Elith_DS_V))
summary_DS
summary_DS_bygroup
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
require(openxlsx)
write.xlsx(summary_DS, file = "Postdoc-R/Exported Tables/summary_DS.xlsx")
write.xlsx(summary_DS_bygroup, file = "Postdoc-R/Exported Tables/summary_DS_bygroup.xlsx")
#9. regression of PIC and sinkvel of cells and liths
#a. for cells
PIC_reg <- lm(SinkVel~PICpercellpg, data=PIC) #essentially perfect fit: summary may be unreliable haha
summary(PIC_reg)

Call:
lm(formula = SinkVel ~ PICpercellpg, data = PIC)

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0115036 -0.0029329  0.0004329  0.0021756  0.0113796 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.0180085  0.0009620   18.72   <2e-16 ***
PICpercellpg 0.0177476  0.0001254  141.58   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.005175 on 44 degrees of freedom
Multiple R-squared:  0.9978,    Adjusted R-squared:  0.9978 
F-statistic: 2.004e+04 on 1 and 44 DF,  p-value: < 2.2e-16
plot(residuals.lm(PIC_reg))
layout(matrix(1:4,2,2))

plot(PIC_reg)

coef(PIC_reg)
 (Intercept) PICpercellpg 
  0.01800852   0.01774764 
# coef(PIC_reg)
#(Intercept) PICpercellpg 
#0.01800852   0.01774764 
cor(PIC$PICpercellpg, PIC$SinkVel)
[1] 0.9989042
#cor = 0.9989042
beta_reg <- lm(beta_d~PICpercellpg, data=PIC)
plot(residuals.lm(beta_reg))
coef(beta_reg)
 (Intercept) PICpercellpg 
1.639233e-07 3.243054e-07 
#coef(beta_reg)
# (Intercept) PICpercellpg 
#1.639233e-07 3.243054e-07
E_DS_HV_reg <- lm(E_DS_HV~PICpercellpg, data=PIC)
E_DS_V_reg <- lm(E_DS_V~PICpercellpg, data=PIC)
plot(residuals.lm(E_DS_HV_reg))
plot(residuals.lm(E_DS_V_reg))
coef(E_DS_HV_reg)
 (Intercept) PICpercellpg 
    1.639233     3.243054 
coef(E_DS_V_reg)
 (Intercept) PICpercellpg 
 0.001639233  0.003243054 
#b. for liths
perlith_reg <- lm (perlithpg~PICpercellpg, data=PIC)
plot(resid(perlith_reg))

coef(perlith_reg)
  (Intercept)  PICpercellpg 
-6.547738e-17  5.000000e-02 
sinkvel_lith_reg <- lm(SinkVel_lith~PICpercellpg, data = PIC)
summary(sinkvel_lith_reg)
essentially perfect fit: summary may be unreliable

Call:
lm(formula = SinkVel_lith ~ PICpercellpg, data = PIC)

Residuals:
       Min         1Q     Median         3Q        Max 
-1.043e-16 -3.686e-17 -2.422e-18  4.040e-17  7.364e-17 

Coefficients:
              Estimate Std. Error   t value Pr(>|t|)    
(Intercept)  1.673e-02  8.512e-18 1.965e+15   <2e-16 ***
PICpercellpg 1.115e-02  1.109e-18 1.005e+16   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 4.579e-17 on 44 degrees of freedom
Multiple R-squared:      1, Adjusted R-squared:      1 
F-statistic: 1.011e+32 on 1 and 44 DF,  p-value: < 2.2e-16
plot(residuals.lm(sinkvel_lith_reg))
layout(matrix(1:4,2,2))

plot(sinkvel_lith_reg)

coef(sinkvel_lith_reg)
 (Intercept) PICpercellpg 
  0.01672753   0.01115169 
beta_lith_reg <- lm(beta_d_lith~PICpercellpg, data=PIC)
plot(residuals.lm(beta_lith_reg))
coef(beta_lith_reg)
 (Intercept) PICpercellpg 
2.302277e-07 1.528542e-07 
Elith_DS_HV_reg <- lm(Elith_DS_HV~PICpercellpg, data=PIC)
Elith_DS_V_reg <- lm(Elith_DS_V~PICpercellpg, data=PIC)
plot(residuals.lm(Elith_DS_HV_reg))
plot(residuals.lm(Elith_DS_V_reg))

coef(Elith_DS_HV_reg)
 (Intercept) PICpercellpg 
    2.302277     1.528542 
coef(Elith_DS_V_reg)
 (Intercept) PICpercellpg 
 0.002302277  0.001528542 
# 9. make new dataframe depending on experimental PIC values
# make a prediction based on PIC values
require(truncnorm)
require(Rmisc)
summary(PIC$PICpercellpg)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-1.5873  0.5523  2.3009  4.6739  6.1204 20.1442 
summarySE(data=PIC, measurevar="PICpercellpg")
PIC_newdata <- as.data.frame(rtruncnorm(n=1000, a=-1.6, b=20.14, mean=4.7, sd=6.15))
#rename column. rename function in plyr 
library(plyr)
PIC_newdata <- rename (PIC_newdata, c ("rtruncnorm(n = 1000, a = -1.6, b = 20.14, mean = 4.7, sd = 6.15)" = 
                                         "PICpercellpg"))
PIC_newdata <- mutate(PIC_newdata, group = ifelse(PICpercellpg < 4 , "naked", "calcified"))
ggplotly(ggplot(data=PIC_newdata, aes(x=group, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2) +
           theme_Publication())

PIC_newdata$group2 <- case_when(
  PIC_newdata$PICpercellpg <2  ~ "naked_bouyant",
  PIC_newdata$PICpercellpg >2 & PIC_newdata$PICpercellpg < 4 ~ "naked/calcified uncertain",
  PIC_newdata$PICpercellpg >4 & PIC_newdata$PICpercellpg < 10 ~ "moderately calcified",
  PIC_newdata$PICpercellpg >10 ~ "strongly calcified", 
  TRUE ~ as.character(PIC_newdata$PICpercellpg)
)
ggplotly(ggplot(data=PIC_newdata, aes(x=group2, y=PICpercellpg)) + 
           geom_boxplot()+geom_point(size=2) +theme_Publication())

#a. for host
PIC_newdata$SinkVel.pred <- predict(PIC_reg, data.frame(PIC_newdata))
PIC_newdata_reg <- lm(SinkVel.pred~PICpercellpg, data=PIC_newdata) 
coef(PIC_newdata_reg)
 (Intercept) PICpercellpg 
  0.01800852   0.01774764 
#same coef as PIC_reg
#> coef(PIC_newdata_reg)
#(Intercept) PICpercellpg 
#0.01800852   0.01774764 
plot(resid(PIC_newdata_reg))

ggplot(data=PIC_newdata, aes(x=PICpercellpg, y=SinkVel.pred)) +geom_point(size=2) +theme_Publication()+
  labs(y = expression("Predicted Sinking velocity"~("m"~day^-1)), x = expression("PIC"~cell^-1)) 

PIC_newdata$beta.pred <- predict(beta_reg, data.frame(PIC_newdata))
PIC_newdata$E_DS_V.pred <- predict(E_DS_V_reg, data.frame(PIC_newdata))
PIC_newdata$E_DS_HV.pred <- predict(E_DS_HV_reg, data.frame(PIC_newdata))
ggplot(data=PIC_newdata, aes(x=PICpercellpg, y=E_DS_V.pred)) +geom_point(size=5, aes(color=group2)) +
  theme_Publication() + geom_smooth() +
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")

  
PICbeta_new <- ggplot(data=PIC_newdata, aes(x=PICpercellpg, y=beta.pred)) +
  geom_point(size=5, aes(color=PICpercellpg))+
  scale_colour_gradient(name="PIC", guide=guide_colorbar(direction = "vertical", barheight=10))+
  theme_Publication() + 
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
  labs(y = expression(beta~("Predicted Encounters"~cm^3~day^-1)), x = expression("PIC"~cell^-1))+
  theme(legend.position = "right")
PICbeta_new

#b. for liths
PIC_newdata$perlithpg.pred <- predict(perlith_reg, data.frame(PIC_newdata))
PIC_newdata$SinkVel.pred.lith <- predict(sinkvel_lith_reg, data.frame(PIC_newdata))
sinkvel_lith_reg.pred <- lm(SinkVel.pred.lith~PICpercellpg, data=PIC_newdata) 
coef(sinkvel_lith_reg.pred)
 (Intercept) PICpercellpg 
  0.01672753   0.01115169 
#same coef as sinkvel_lith_reg
#> coef(sinkvel_lith_reg.pred)
#(Intercept) PICpercellpg 
# 0.01672753   0.01115169 
plot(resid(sinkvel_lith_reg.pred))

ggplot(data=PIC_newdata, aes(x=perlithpg.pred, y=SinkVel.pred.lith)) +geom_point(size=2) +theme_Publication()+
  labs(y = expression("Predicted Sinking velocity of Liths"~("m"~day^-1)), x = expression("PIC"~lith^-1)) 

PIC_newdata$beta.pred.lith <- predict(beta_lith_reg, data.frame(PIC_newdata))
PIC_newdata$E_DS_V.pred.lith <- predict(Elith_DS_HV_reg, data.frame(PIC_newdata))
PIC_newdata$E_DS_HV.pred.lith <- predict(Elith_DS_HV_reg, data.frame(PIC_newdata))
ggplot(data=PIC_newdata, aes(x=perlithpg.pred, y=E_DS_V.pred.lith)) +geom_point(size=5, aes(color=group2)) +
  theme_Publication() + scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+ geom_smooth()

PICbeta_new.lith <- ggplot(data=PIC_newdata, aes(x=perlithpg.pred, y=beta.pred.lith)) +
  geom_point(size=5, aes(color=PICpercellpg))+
  scale_colour_gradient(name="PIC", guide=guide_colorbar(direction = "vertical", barheight=10))+
  theme_Publication() + 
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
  labs(y = expression(beta~("Predicted Encounters of lith " ~cm^3~day^-1)), x = expression("PIC"~lith^-1))+
  theme(legend.position = "right")
PICbeta_new.lith

#summaries
summary_DS_newdata_bygroup2 <- ddply(PIC_newdata, .(group2), summarize,  PICpercellpg=mean(PICpercellpg), SinkVel.pred=mean(SinkVel.pred),beta.pred= mean (beta.pred), E_DS_V.pred= mean(E_DS_V.pred), E_DS_HV.pred=mean(E_DS_HV.pred))
summary_DS_bygroup.pred <- ddply(PIC_newdata, .(group2), summarize,  PICpercellpg=mean(PICpercellpg), 
                            perlithpg.pred = mean(perlithpg.pred), SinkVel.pred=mean(SinkVel.pred),
                            beta.pred= mean (beta.pred), E_DS_V.pred= mean(E_DS_V.pred), 
                            E_DS_HV.pred=mean(E_DS_HV.pred), 
                            SinkVel.pred.lith=mean(SinkVel.pred.lith),beta.pred.lith= mean (beta.pred.lith),
                            E_DS_V.pred.lith= mean(E_DS_V.pred.lith), E_DS_HV.pred.lith=mean(E_DS_HV.pred.lith))
summary_DS_bygroup.pred
write.xlsx(summary_DS_bygroup.pred, file = "Postdoc-R/Exported Tables/summary_DS_bygroup.pred.xlsx")
cannot create file 'Postdoc-R/Exported Tables/summary_DS_bygroup.pred.xlsx', reason 'No such file or directory'

turbulence

#TURBULENCE
#disrate is cm2/s3
#make data frame
disrate <- rep_len(10^(-8:-2), length.out=14)
calc <- rep_len(c("calcified"), length.out=7)
naked <- rep_len(c("naked"), length.out=7)
group <- c(calc, naked)
turb <- as.data.frame(cbind(disrate, group))
turb <- mutate(turb, rad = ifelse(group == "naked" ,  1.8E-6,  2.3E-6)) #in m
turb$disrate <- as.numeric(as.character(turb$disrate))
turb$Kol <- ((v^3/turb$disrate)^0.25)*100 #Kolmogorov length scale in cm
#everything is below 1 cm, use eqn 2 in TK 
turb$beta_d <- (4.2*pi*((turb$disrate/(v*100^2))^0.5)*(((turb$rad+Rehv)*100)^3))*86400 
turb$beta_Heidi <- (0.42*pi*((turb$disrate/(v*100^2))^0.5)*(((turb$rad+Rehv)*100)^3))*86400
#check encounters
#use TK, in cm3 s
turb$E_turb_HV <- (turb$beta_d*hostnum*virnum) #E calculated with Virus and Host (10:1 MOI)
turb$E_turb_V <- (turb$beta_d*virnum) #E calculated with virus only
breaks <- 10^(-10:10)
minor_breaks <- rep(1:9, 21)*(10^rep(-10:10, each=9))
ggplot(data = turb, aes(x = disrate, y = beta_d, color=group)) + geom_point(size =5) +
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks() +
  theme_Publication()

library(scales)
ggplot(data = turb, aes(x = disrate, y = E_turb_V, color=group)) + geom_point(size =5) +
   scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks()+
  theme_Publication()

add beta kernels and plot

#extract mean betas from PIC_newdata
beta_DS <- summarySE (PIC_newdata, measurevar = "beta.pred", groupvars = c("group", "group2"))
all <- Reduce(function(x,y) merge(x,y,by="group",all=TRUE) ,list(BM, beta_DS, turb))
#beta_d.x=BM, beta.pred=DS, beta_d.y=turb
#rename beta.pred to beta_pred so I can use grep. 
#all <- rename (all, c("beta_d.x" = "beta_BM", "beta.pred" = "beta_DS", "beta_d.y" = "beta_turb"))
library(data.table)
NT = data.table(all, key="group2")
allbetas = NT[, list(group=group, disrate=disrate, beta_BM=beta_d.x, beta_DS=beta.pred, beta_turb = beta_d.y, 
                     beta_BM_DS =beta_d.x + beta.pred,
                     beta_DS_turb = beta.pred + beta_d.y,
                     beta_BM_turb = beta_d.x + beta_d.y,
                     beta_all = beta_d.x + beta_d.y + beta.pred), 
              by=c("group2")]
ggplot(allbetas, aes(disrate, y = value, color=group2)) + 
  geom_line(aes(y = beta_DS_turb, linetype = "DS+turb"), size=1) + 
  geom_line(aes(y = beta_all, linetype = "BM+DS+turb"), size=1)+
  geom_line(aes(y = beta_turb, linetype = "turb"), size=1)+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=7),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks()+
  theme_Publication()

#encounters
#melt data
allbetas.melt <- melt (allbetas, id.vars = c("group2", "group", "disrate"), value.name = "beta_d", 
                       variable.name = "betakernel")
allbetas.melt$group2 <- factor (allbetas.melt$group2,levels= c("naked_bouyant", "naked/calcified uncertain",
                                                       "moderately calcified", "strongly calcified"),
                                                       labels = c("naked", "naked/calcified uncertain",
                                                                  "moderately calcified", "strongly calcified"))
allbetas.melt$E_V <- allbetas.melt$beta_d*virnum
ggplot(allbetas.melt, aes(disrate, y = E_V, color=group2)) + 
  geom_line(size=1)+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=7),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks() + facet_grid(~betakernel)

#subset data
graph1 <- subset(allbetas.melt, betakernel %in% c ("beta_BM", "beta_DS", "beta_BM_DS"))
graph2 <- subset(allbetas.melt, betakernel %in% c ("beta_turb", "beta_DS_turb", "beta_BM_turb", "beta_all"))
ggplot(graph1, aes(group2, y = E_V, color=betakernel)) + 
  geom_jitter(size=5)+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks(sides = "l")+
  theme_Publication()

graph1.sum <- summarySE (graph1, measurevar = "E_V", groupvars = c("betakernel", "group2"))
ggplot(graph1.sum, aes(group2, y = E_V, color=betakernel)) + 
  geom_point(size=5,  position=position_dodge(0.2))+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks(sides = "l")+
  theme_Publication()

ggplot(data=allbetas.melt %>% filter(betakernel %in% c("beta_turb", "beta_all")), 
       aes(x=disrate,y = E_V, color=group2, linetype=betakernel)) + 
  geom_line(size=1, position=position_jitter(w=0.02, h=0))+
   scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=7),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks()+
  theme_Publication()

ggplot(data=allbetas.melt %>% filter(betakernel %in% c("beta_all")), 
       aes(x=disrate,y = E_V, color=group2)) + 
  geom_line(size=1, position=position_jitter(w=0.02, h=0))+
   scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=7),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks()+
  theme_Publication()

LS0tDQp0aXRsZTogImJldGEga2VybmVsIGZpbmFsIG5vdGVib29rIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gDQoNClRyeSBleGVjdXRpbmcgdGhpcyBjaHVuayBieSBjbGlja2luZyB0aGUgKlJ1biogYnV0dG9uIHdpdGhpbiB0aGUgY2h1bmsgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDdHJsK1NoaWZ0K0VudGVyKi4gDQoNCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4NCg0KV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDdHJsK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuDQoNClRoZSBwcmV2aWV3IHNob3dzIHlvdSBhIHJlbmRlcmVkIEhUTUwgY29weSBvZiB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvci4gQ29uc2VxdWVudGx5LCB1bmxpa2UgKktuaXQqLCAqUHJldmlldyogZG9lcyBub3QgcnVuIGFueSBSIGNvZGUgY2h1bmtzLiBJbnN0ZWFkLCB0aGUgb3V0cHV0IG9mIHRoZSBjaHVuayB3aGVuIGl0IHdhcyBsYXN0IHJ1biBpbiB0aGUgZWRpdG9yIGlzIGRpc3BsYXllZC4NCg0KYGBge3J9DQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCiN2YWx1ZXMgbmVlZGVkIA0KDQpLPSAxLjM4MDY0ODUyKigxMCleLTIzICNtMiBrZy8gczIgSyBib2x0em1hbm4gY29uc3RhbnQNCm11PSAxLjEyNiooMTApXi0zICNrZy9tIHMgZHluYW1pYyB2aXNjb3NpdHkgaW4gMThDDQp2PSAxLjA5OSooMTApXi02ICNtMi9zIGtpbmVtYXRpYyB2aXNjb3NpdHkgaW4gMThDDQpSZWhfY2FsYz0gMi4zRS02ICNpbiBtIHJhZGl1cyBFaHV4DQpSZWhfbmFrZWQ9IDEuOEUtNiAjaW4gbSByYWRpdXMgRWh1eA0KUmVodj0gOTAqKDEwKV4tOSAjaW4gbSByYWRpdXMgdmlydXMNClRlbXAgPSAxOCsyNzMuMTUgI3RlbXAgaW4ga2VsdmluLCBoZXJlIGFzc3VtaW5nIDE4Qw0KRGVuX09jTSA9IDEuMDUgI2cvY20zIGRlbnNpdHkgb3JnYW5pYyBjZWxsIG1hdHRlcg0KRGVuX0NIMk89IDEuMDI1ICNnL2NtMyBkZW5zaXR5IHNlYXdhdGVyIGF0IDE4Qw0KaG9zdG51bSA8LSAoMTApXjMNCnZpcm51bSA8LSAoMTApXjQNCg0KcmVxdWlyZSAoZ2dwbG90MikNCnJlcXVpcmUocGxvdGx5KQ0KcmVxdWlyZShncmlkKQ0KcmVxdWlyZShnZ3RoZW1lcykNCnJlcXVpcmUgKGRwbHlyKQ0KcmVxdWlyZShwbHlyKQ0Kc291cmNlICgidGhlbWVfUHVibGljYXRpb24uUiIpDQpzb3VyY2UoInJlc2l6ZXdpbi5SIikNCnJlc2l6ZS53aW4oMTIsOSkNCmdyaWQubmV3cGFnZSgpDQoNCmBgYA0KDQpmb3IgQnJvd25pYW4gbW90aW9uDQoNCmBgYHtyfQ0KI0Jyb3duaWFuIG1vdGlvbiAoQk0pDQojMS4gbWFrZSBhIGRhdGEgZnJhbWUNCkJNIDwtIGRhdGEuZnJhbWUgKGdyb3VwPSBjKCJuYWtlZCIsICJjYWxjaWZpZWQiKSwgcmFkPSBjKDEuOEUtNiwgMi4zRS02KSkgDQoNCiMyLiBjYWxjdWxhdGUgYmV0YSAoYmV0YSkNCkJNJGJldGFfcyA8LSAoMiooSyooMTApXjQpKlRlbXAqKCgoQk0kcmFkK1JlaHYpKjEwMCleMikpLygoMyptdSoxMCkqKEJNJHJhZCpSZWh2KjFlNCkpICNtMy9zDQpCTSRiZXRhX2QgPC0gQk0kYmV0YV9zKjg2NDAwICN0byBjbTMvZGF5DQoNCiMgZ28gYmFjayB0byB0aGlzIGxhdGVyDQojMy4gY2FsY3VsYXRlIGVuY291bnRlcnMgKEUpDQpCTSRFIDwtIEJNJGJldGFfZCpob3N0bnVtDQpCTSRFX0hWIDwtIEJNJGJldGFfZCp2aXJudW0qaG9zdG51bQ0KDQpCTQ0KYGBgDQoNCkRpZmZlcmVudGlhbCBzZXR0bGluZyAoRFMpDQoNCmBgYHtyfQ0KI0RpZmZlcmVudGlhbCBzZXR0bGluZyAoRFMpDQojMS4gcmVhZCBpbiBQSUMgZGF0YQ0KbGlicmFyeShyZWFkcikgI2Fsd2F5cyB1c2UgcmVhZHIgbm90IGJhc2VSDQoNCnNldHdkKCJEOi9SIHByb2dyYW0iKQ0KUElDIDwtIHJlYWRfY3N2KCJQb3N0ZG9jLVIvQ1NWIEZpbGVzL1BJQy5jc3YiKQ0KDQpQSUMkU3RyYWluIDwtIGFzLmZhY3RvcihQSUMkU3RyYWluKQ0KUElDJFJlcGxpY2F0ZSA8LSBhcy5mYWN0b3IoUElDJFJlcGxpY2F0ZSkNCg0KI2NlcnRhaW4gY2hhbmdlcyBpbiBkYXRhLnRhYmxlIEFQSSBtYWRlIGNhbGN1bGF0aW5nIGluc2lkZSB0aGUgbGlzdCBkYXRhLnRhYmxlIHRvIG5vdCB3b3JrDQoNCiMyLiBjYWxjdWxhdGUgUElDDQpQSUMkUElDIDwtIFBJQyRUQy1QSUMkQUMNClBJQyRQSUNwZXJjZWxsIDwtIChQSUMkUElDL1BJQyRDZWxsY291bnQpKigxMCleLTMjaW4gZw0KUElDJFBJQ3BlcmNlbGxwZyA8LSBQSUMkUElDcGVyY2VsbCoxZTEyDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9U3RyYWluLCB5PVBJQ3BlcmNlbGxwZykpICsgZ2VvbV9ib3hwbG90KCkrZ2VvbV9wb2ludChzaXplPTIpICt0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQpgYGANCg0KYGBge3J9DQoNCiMzLiBjYWxjdWxhdGUgZGVuc2l0eSBvZiBjZWxscyAoZGVuKQ0KUElDIDwtIG11dGF0ZShQSUMsIGdyb3VwID0gaWZlbHNlKFBJQ3BlcmNlbGxwZyA8IDQgLCAibmFrZWQiLCAiY2FsY2lmaWVkIikpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9Z3JvdXAsIHk9UElDcGVyY2VsbHBnKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MiwgYWVzKGNvbG9yPVN0cmFpbikpKw0KICAgICAgICAgICB0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQpQSUMgPC0gbXV0YXRlKFBJQywgcmFkID0gaWZlbHNlKGdyb3VwID09ICJuYWtlZCIgLCAgMS44RS02LCAgMi4zRS02KSkgI2luIG0NCg0KUElDJHZvbHVtZSA8LSAoNC8zKSpwaSooUElDJHJhZCoxMDApXjMgI2luIGNtMw0KUElDJERlbl9jZWxsIDwtIFBJQyRQSUNwZXJjZWxsL1BJQyR2b2x1bWUgI2cvY20zDQpQSUMkRGVuX2NlbGx0b3RhbCA8LSBQSUMkRGVuX2NlbGwrRGVuX09jTQ0KDQpnZ3Bsb3RseShnZ3Bsb3QoZGF0YT1QSUMsIGFlcyh4PVN0cmFpbiwgeT1EZW5fY2VsbHRvdGFsLCBjb2xvcj1ncm91cCkpICsgZ2VvbV9ib3hwbG90KCkrZ2VvbV9wb2ludChzaXplPTIpIA0KICAgICAgICAgK3RoZW1lX1B1YmxpY2F0aW9uKCkpDQoNCiNzb21lIHN0cmFpbnMgdGhhdCBhcmUgIm5ha2VkIiBoYXZlIFBJQzwyLiBJIGNob3NlIHRvIGlnbm9yZSB0aGlzIHNpbmNlIGluIHRoZSBsbSBtb2RlbCBJIGRvIG5vdCB1c2UNCiNzdHJhaW4gYXMgYSBmYWN0b3IsIHJhdGhlciBkYXRhIGlzIHRyZWF0ZWQgYXMgYSB3aG9sZSAoZS5nLiwgbm8gZ3JvdXBpbmcpDQoNCiM0LiBjYWxjdWxhdGUgc2lua2luZyB2ZWxvY2l0eSBvZiBjZWxscw0KUElDJFNpbmtWZWwgPC0gKCgyKigoUElDJHJhZCoxMDApXjIpKig5ODEpKihQSUMkRGVuX2NlbGx0b3RhbC1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgI21ldGVyIHBlciBkYXkNCg0KI2cgaXMgY29udmVydGVkIHRvIHBlciBkYXksIDg2NCBpcyB0aGUgb25lIHRoYXQgY29udmVydHMgY20vcyB0byBtL2RheQ0KDQojcGxvdCBzaW5raW5nIHZlbG9jaXR5IHZzIGNhbGNpZmljYXRpb24NCg0KZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9U2lua1ZlbCwgY29sb3I9U3RyYWluLCBzaGFwZT1ncm91cCkpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogICAgbGFicyh5ID0gZXhwcmVzc2lvbigiU2lua2luZyB2ZWxvY2l0eSJ+KCJtIn5kYXleLTEpKSwgeCA9IGV4cHJlc3Npb24oIlBJQyJ+Y2VsbF4tMSkpICsNCiAgICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTIpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpDQoNCiM1LiBjYWxjdWxhdGUgc2lua3ZlbCBvZiB2aXJ1c2VzDQoNCkRlbl92aXJ1cyA8LSAxLjA5ICNkYXRhIGZyb20gQmVuIEQuIGZyZXNoIEVoVi0yMDcgZGVuc2l0eS4gb2xkIGRlbnNpdHkgb2YgRWhWLTIwNyBpcyAxLjE5DQpFaHZfU2lua1ZlbCA8LSAoKDIqKChSZWh2KjEwMCleMikqKDk4MSkqKERlbl92aXJ1cy1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgICNlcXVhbHMgdG8gMA0KDQojNi4gY2FsY3VsYXRlIGJldGEga2VybmVscw0KUElDJGJldGFfcyA8LSBwaSooKChQSUMkcmFkK1JlaHYpKjEwMCleMikqKGFicygoUElDJFNpbmtWZWwtRWh2X1NpbmtWZWwpLzg2NCkpICNpbiBlbmNvdW50ZXJzIGNtMy9zDQpQSUMkYmV0YV9kIDwtIFBJQyRiZXRhX3MqODY0MDAgI2luIGNtMy9kYXkNCg0KU2lua3ZlbGJldGEucGxvdDwtIGdncGxvdChkYXRhPVBJQywgYWVzKHg9U2lua1ZlbCwgeT1iZXRhX2QsIGNvbG9yPVN0cmFpbiwgc2hhcGU9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZT01KSsNCiAgdGhlbWVfUHVibGljYXRpb24oKSsNCiAgbGFicyh4ID0gZXhwcmVzc2lvbigiU2lua2luZyB2ZWxvY2l0eSJ+KCJtIn5kYXleLTEpKSwgeSA9IGV4cHJlc3Npb24oYmV0YX4oIkVuY291bnRlcnMiIH4gY21eM35kYXleLTEpKSkgKw0KIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikNCg0KU2lua3ZlbGJldGEucGxvdCAjY2hhbmdlIHRpY2tzDQoNCmdncGxvdGx5KFNpbmt2ZWxiZXRhLnBsb3QpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9U3RyYWluLCB5PVNpbmtWZWwpKSArIGdlb21fYm94cGxvdCgpK3RoZW1lX1B1YmxpY2F0aW9uKCkpDQoNCmdncGxvdChkYXRhPVBJQywgYWVzKHg9UElDcGVyY2VsbHBnLCB5PWJldGFfZCwgY29sb3I9U3RyYWluKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbihiZXRhfigiRW5jb3VudGVycyJ+Y21eM35kYXleLTEpKSwgeCA9IGV4cHJlc3Npb24oIlBJQyJ+Y2VsbF4tMSkpICArDQpzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTIpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpDQoNCmBgYA0KDQpgYGB7cn0NCiM3LiBjYWxjdWxhdGUgYmV0YSBhbmQgZW5jb3VudGVycw0KI2JldGEgYXJlIGluIGNlbGxzIGNtMy8gZGF5IHRoZW4gZW5jb3VudGVycyBhcmUgdG8gY2VsbHMvY20zIGRheQ0KUElDJEVfRFNfSFYgPC0gKFBJQyRiZXRhX2QqdmlybnVtKmhvc3RudW0pICAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgYW5kIEhvc3QgKDEwOjEgTU9JKQ0KUElDJEVfRFNfViA8LSAoUElDJGJldGFfZCp2aXJudW0pICNFIGNhbGN1bGF0ZWQgd2l0aCBWaXJ1cw0KDQojOC4gY2FsY3VsYXRlIGZvciBsaXRoIHBhcmFtZXRlcnMNCg0KbGl0aHZvbCA8LSAzKjFlLTEyICNpbiBjbTMsIGZyb20gQ0oncyBwYXBlcg0KUElDJHBlcmxpdGggPC0gUElDJFBJQ3BlcmNlbGwvMjAgI2luIGcsIGFzc3VtaW5nIDIwIGxpdGhzIGF0dGFjaGVkDQpQSUMkcGVybGl0aHBnIDwtIFBJQyRwZXJsaXRoKjFlMTIgI2luIHBnDQpQSUMkRGVubGl0aCA8LSAoUElDJHBlcmxpdGgvbGl0aHZvbCkgKyBEZW5fT2NNICNpbiBnL2NtMywgd2l0aCBvcmdhbmljIG1hdHRlciBhdHRhY2hlZA0KcmFkX2xpdGggPC0gMkUtNiAjaW4gbSByYWRpdXMNCg0KUElDJFNpbmtWZWxfbGl0aCA8LSAoKDIqKChyYWRfbGl0aCoxMDApXjIpKig5ODEpKihQSUMkRGVubGl0aC1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgI21ldGVyIHBlciBkYXkNClBJQyRiZXRhX3NfbGl0aCA8LSBwaSooKChyYWRfbGl0aCtSZWh2KSoxMDApXjIpKihhYnMoKFBJQyRTaW5rVmVsX2xpdGgtRWh2X1NpbmtWZWwpLzg2NCkpICNpbiBlbmNvdW50ZXJzIGNtMy9zDQpQSUMkYmV0YV9kX2xpdGggPC0gUElDJGJldGFfc19saXRoKjg2NDAwICNpbiBjbTMvZGF5DQoNCmdncGxvdChkYXRhPVBJQywgYWVzKHg9cGVybGl0aHBnLCB5PVNpbmtWZWxfbGl0aCwgY29sb3I9U3RyYWluLCBzaGFwZT1ncm91cCkpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oIlNpbmtpbmcgdmVsb2NpdHkifigibSJ+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMifmxpdGheLTEpKSANCg0KUElDJEVsaXRoX0RTX0hWIDwtIChQSUMkYmV0YV9kX2xpdGgqdmlybnVtKmhvc3RudW0pICAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgYW5kIEhvc3QgKDEwOjEgTU9JKQ0KUElDJEVsaXRoX0RTX1YgPC0gKFBJQyRiZXRhX2RfbGl0aCp2aXJudW0pICNFIGNhbGN1bGF0ZWQgd2l0aCBWaXJ1cw0KDQpyZXF1aXJlIChkcGx5cikNCg0KUElDJGdyb3VwMiA8LSBjYXNlX3doZW4oDQogIFBJQyRQSUNwZXJjZWxscGcgPDIgIH4gIm5ha2VkX2JvdXlhbnQiLA0KICBQSUMkUElDcGVyY2VsbHBnID4yICYgUElDJFBJQ3BlcmNlbGxwZyA8IDQgfiAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogIFBJQyRQSUNwZXJjZWxscGcgPjQgJiBQSUMkUElDcGVyY2VsbHBnIDwgMTAgfiAibW9kZXJhdGVseSBjYWxjaWZpZWQiLA0KICBQSUMkUElDcGVyY2VsbHBnID4xMCB+ICJzdHJvbmdseSBjYWxjaWZpZWQiLCANCiAgVFJVRSB+IGFzLmNoYXJhY3RlcihQSUMkUElDcGVyY2VsbHBnKQ0KKQ0KDQpicmVha3MgPC0gMTBeKC0xMDoxMCkNCg0KZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1TaW5rVmVsLCB5PUVfRFNfSFYsIGNvbG9yPVN0cmFpbiwgc2hhcGU9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikNCg0KDQpnZ3Bsb3QoZGF0YT1QSUMsIGFlcyh4PVNpbmtWZWwsIHk9RV9EU19WLCBjb2xvcj1TdHJhaW4sIHNoYXBlPWdyb3VwKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKQ0KDQoNCmdncGxvdChkYXRhPVBJQywgYWVzKHg9U2lua1ZlbF9saXRoLCB5PUVsaXRoX0RTX1YsIGNvbG9yPVN0cmFpbiwgc2hhcGU9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZT01KSArIA0KICB0aGVtZV9QdWJsaWNhdGlvbigpICsgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0zKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKQ0KDQoNCg0Kc3VtbWFyeV9EUyA8LSBkZHBseShQSUMsIC4oU3RyYWluKSwgc3VtbWFyaXplLCAgUElDcGVyY2VsbHBnPW1lYW4oUElDcGVyY2VsbHBnKSwgcGVybGl0aHBnID0gbWVhbihwZXJsaXRocGcpLCANCiAgICAgICAgICAgICAgICAgICAgRGVuX2NlbGx0b3RhbCA9IG1lYW4gKERlbl9jZWxsdG90YWwpLA0KICAgICAgICAgICAgICAgICAgICBTaW5rVmVsPW1lYW4oU2lua1ZlbCksYmV0YV9kPW1lYW4oYmV0YV9kKSwgRV9EU19WPSBtZWFuKEVfRFNfViksIEVfRFNfSFY9bWVhbihFX0RTX0hWKSwNCiAgICAgICAgICAgICAgICAgICAgU2lua1ZlbF9saXRoPW1lYW4gKFNpbmtWZWxfbGl0aCksIGJldGFfZF9saXRoPW1lYW4gKGJldGFfZF9saXRoKSwgRWxpdGhfRFNfSFY9bWVhbiAoRWxpdGhfRFNfSFYpLA0KICAgICAgICAgICAgICAgICAgICBFbGl0aF9EU19WPW1lYW4gKEVsaXRoX0RTX1YpKQ0KDQpzdW1tYXJ5X0RTX2J5Z3JvdXAgPC0gZGRwbHkoUElDLCAuKGdyb3VwMiksIHN1bW1hcml6ZSwgIFBJQ3BlcmNlbGxwZz1tZWFuKFBJQ3BlcmNlbGxwZyksIHBlcmxpdGhwZyA9IG1lYW4ocGVybGl0aHBnKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVuX2NlbGx0b3RhbCA9IG1lYW4gKERlbl9jZWxsdG90YWwpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNpbmtWZWw9bWVhbihTaW5rVmVsKSxiZXRhX2Q9bWVhbihiZXRhX2QpLCBFX0RTX1Y9IG1lYW4oRV9EU19WKSwgRV9EU19IVj1tZWFuKEVfRFNfSFYpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaW5rVmVsX2xpdGg9bWVhbiAoU2lua1ZlbF9saXRoKSwgYmV0YV9kX2xpdGg9bWVhbiAoYmV0YV9kX2xpdGgpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGl0aF9EU19IVj1tZWFuIChFbGl0aF9EU19IViksIEVsaXRoX0RTX1Y9bWVhbiAoRWxpdGhfRFNfVikpDQoNCnN1bW1hcnlfRFMNCnN1bW1hcnlfRFNfYnlncm91cA0KDQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCnJlcXVpcmUob3Blbnhsc3gpDQp3cml0ZS54bHN4KHN1bW1hcnlfRFMsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTLnhsc3giKQ0Kd3JpdGUueGxzeChzdW1tYXJ5X0RTX2J5Z3JvdXAsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTX2J5Z3JvdXAueGxzeCIpDQoNCmBgYA0KDQpgYGB7cn0NCg0KIzkuIHJlZ3Jlc3Npb24gb2YgUElDIGFuZCBzaW5rdmVsIG9mIGNlbGxzIGFuZCBsaXRocw0KDQojYS4gZm9yIGNlbGxzDQpQSUNfcmVnIDwtIGxtKFNpbmtWZWx+UElDcGVyY2VsbHBnLCBkYXRhPVBJQykgI2Vzc2VudGlhbGx5IHBlcmZlY3QgZml0OiBzdW1tYXJ5IG1heSBiZSB1bnJlbGlhYmxlIGhhaGENCnN1bW1hcnkoUElDX3JlZykNCnBsb3QocmVzaWR1YWxzLmxtKFBJQ19yZWcpKQ0KbGF5b3V0KG1hdHJpeCgxOjQsMiwyKSkNCnBsb3QoUElDX3JlZykNCg0KY29lZihQSUNfcmVnKQ0KIyBjb2VmKFBJQ19yZWcpDQojKEludGVyY2VwdCkgUElDcGVyY2VsbHBnIA0KIzAuMDE4MDA4NTIgICAwLjAxNzc0NzY0IA0KDQpjb3IoUElDJFBJQ3BlcmNlbGxwZywgUElDJFNpbmtWZWwpDQojY29yID0gMC45OTg5MDQyDQoNCmJldGFfcmVnIDwtIGxtKGJldGFfZH5QSUNwZXJjZWxscGcsIGRhdGE9UElDKQ0KcGxvdChyZXNpZHVhbHMubG0oYmV0YV9yZWcpKQ0KY29lZihiZXRhX3JlZykNCiNjb2VmKGJldGFfcmVnKQ0KIyAoSW50ZXJjZXB0KSBQSUNwZXJjZWxscGcgDQojMS42MzkyMzNlLTA3IDMuMjQzMDU0ZS0wNw0KDQpFX0RTX0hWX3JlZyA8LSBsbShFX0RTX0hWflBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpFX0RTX1ZfcmVnIDwtIGxtKEVfRFNfVn5QSUNwZXJjZWxscGcsIGRhdGE9UElDKQ0KcGxvdChyZXNpZHVhbHMubG0oRV9EU19IVl9yZWcpKQ0KcGxvdChyZXNpZHVhbHMubG0oRV9EU19WX3JlZykpDQpjb2VmKEVfRFNfSFZfcmVnKQ0KY29lZihFX0RTX1ZfcmVnKQ0KDQojYi4gZm9yIGxpdGhzDQpwZXJsaXRoX3JlZyA8LSBsbSAocGVybGl0aHBnflBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpwbG90KHJlc2lkKHBlcmxpdGhfcmVnKSkNCmNvZWYocGVybGl0aF9yZWcpDQpzaW5rdmVsX2xpdGhfcmVnIDwtIGxtKFNpbmtWZWxfbGl0aH5QSUNwZXJjZWxscGcsIGRhdGEgPSBQSUMpDQpzdW1tYXJ5KHNpbmt2ZWxfbGl0aF9yZWcpDQpwbG90KHJlc2lkdWFscy5sbShzaW5rdmVsX2xpdGhfcmVnKSkNCmxheW91dChtYXRyaXgoMTo0LDIsMikpDQpwbG90KHNpbmt2ZWxfbGl0aF9yZWcpDQpjb2VmKHNpbmt2ZWxfbGl0aF9yZWcpDQoNCmJldGFfbGl0aF9yZWcgPC0gbG0oYmV0YV9kX2xpdGh+UElDcGVyY2VsbHBnLCBkYXRhPVBJQykNCnBsb3QocmVzaWR1YWxzLmxtKGJldGFfbGl0aF9yZWcpKQ0KY29lZihiZXRhX2xpdGhfcmVnKQ0KDQpFbGl0aF9EU19IVl9yZWcgPC0gbG0oRWxpdGhfRFNfSFZ+UElDcGVyY2VsbHBnLCBkYXRhPVBJQykNCkVsaXRoX0RTX1ZfcmVnIDwtIGxtKEVsaXRoX0RTX1Z+UElDcGVyY2VsbHBnLCBkYXRhPVBJQykNCnBsb3QocmVzaWR1YWxzLmxtKEVsaXRoX0RTX0hWX3JlZykpDQpwbG90KHJlc2lkdWFscy5sbShFbGl0aF9EU19WX3JlZykpDQpjb2VmKEVsaXRoX0RTX0hWX3JlZykNCmNvZWYoRWxpdGhfRFNfVl9yZWcpDQoNCmBgYA0KDQpgYGB7cn0NCg0KIyA5LiBtYWtlIG5ldyBkYXRhZnJhbWUgZGVwZW5kaW5nIG9uIGV4cGVyaW1lbnRhbCBQSUMgdmFsdWVzDQojIG1ha2UgYSBwcmVkaWN0aW9uIGJhc2VkIG9uIFBJQyB2YWx1ZXMNCnJlcXVpcmUodHJ1bmNub3JtKQ0KcmVxdWlyZShSbWlzYykNCnN1bW1hcnkoUElDJFBJQ3BlcmNlbGxwZykNCnN1bW1hcnlTRShkYXRhPVBJQywgbWVhc3VyZXZhcj0iUElDcGVyY2VsbHBnIikNClBJQ19uZXdkYXRhIDwtIGFzLmRhdGEuZnJhbWUocnRydW5jbm9ybShuPTEwMDAsIGE9LTEuNiwgYj0yMC4xNCwgbWVhbj00LjcsIHNkPTYuMTUpKQ0KDQojcmVuYW1lIGNvbHVtbi4gcmVuYW1lIGZ1bmN0aW9uIGluIHBseXIgDQpsaWJyYXJ5KHBseXIpDQpQSUNfbmV3ZGF0YSA8LSByZW5hbWUgKFBJQ19uZXdkYXRhLCBjICgicnRydW5jbm9ybShuID0gMTAwMCwgYSA9IC0xLjYsIGIgPSAyMC4xNCwgbWVhbiA9IDQuNywgc2QgPSA2LjE1KSIgPSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBJQ3BlcmNlbGxwZyIpKQ0KDQpQSUNfbmV3ZGF0YSA8LSBtdXRhdGUoUElDX25ld2RhdGEsIGdyb3VwID0gaWZlbHNlKFBJQ3BlcmNlbGxwZyA8IDQgLCAibmFrZWQiLCAiY2FsY2lmaWVkIikpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1ncm91cCwgeT1QSUNwZXJjZWxscGcpKSArIGdlb21fYm94cGxvdCgpK2dlb21fcG9pbnQoc2l6ZT0yKSArDQogICAgICAgICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkpDQoNClBJQ19uZXdkYXRhJGdyb3VwMiA8LSBjYXNlX3doZW4oDQogIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA8MiAgfiAibmFrZWRfYm91eWFudCIsDQogIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA+MiAmIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA8IDQgfiAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA+NCAmIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA8IDEwIH4gIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwNCiAgUElDX25ld2RhdGEkUElDcGVyY2VsbHBnID4xMCB+ICJzdHJvbmdseSBjYWxjaWZpZWQiLCANCiAgVFJVRSB+IGFzLmNoYXJhY3RlcihQSUNfbmV3ZGF0YSRQSUNwZXJjZWxscGcpDQopDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1ncm91cDIsIHk9UElDcGVyY2VsbHBnKSkgKyANCiAgICAgICAgICAgZ2VvbV9ib3hwbG90KCkrZ2VvbV9wb2ludChzaXplPTIpICt0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQojYS4gZm9yIGhvc3QNClBJQ19uZXdkYXRhJFNpbmtWZWwucHJlZCA8LSBwcmVkaWN0KFBJQ19yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGFfcmVnIDwtIGxtKFNpbmtWZWwucHJlZH5QSUNwZXJjZWxscGcsIGRhdGE9UElDX25ld2RhdGEpIA0KY29lZihQSUNfbmV3ZGF0YV9yZWcpDQojc2FtZSBjb2VmIGFzIFBJQ19yZWcNCiM+IGNvZWYoUElDX25ld2RhdGFfcmVnKQ0KIyhJbnRlcmNlcHQpIFBJQ3BlcmNlbGxwZyANCiMwLjAxODAwODUyICAgMC4wMTc3NDc2NCANCg0KcGxvdChyZXNpZChQSUNfbmV3ZGF0YV9yZWcpKQ0KDQpnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSwgYWVzKHg9UElDcGVyY2VsbHBnLCB5PVNpbmtWZWwucHJlZCkpICtnZW9tX3BvaW50KHNpemU9MikgK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oIlByZWRpY3RlZCBTaW5raW5nIHZlbG9jaXR5In4oIm0ifmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIn5jZWxsXi0xKSkgDQoNClBJQ19uZXdkYXRhJGJldGEucHJlZCA8LSBwcmVkaWN0KGJldGFfcmVnLCBkYXRhLmZyYW1lKFBJQ19uZXdkYXRhKSkNClBJQ19uZXdkYXRhJEVfRFNfVi5wcmVkIDwtIHByZWRpY3QoRV9EU19WX3JlZywgZGF0YS5mcmFtZShQSUNfbmV3ZGF0YSkpDQpQSUNfbmV3ZGF0YSRFX0RTX0hWLnByZWQgPC0gcHJlZGljdChFX0RTX0hWX3JlZywgZGF0YS5mcmFtZShQSUNfbmV3ZGF0YSkpDQoNCmdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9RV9EU19WLnByZWQpKSArZ2VvbV9wb2ludChzaXplPTUsIGFlcyhjb2xvcj1ncm91cDIpKSArDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkgKyBnZW9tX3Ntb290aCgpICsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKQ0KICANCg0KUElDYmV0YV9uZXcgPC0gZ2dwbG90KGRhdGE9UElDX25ld2RhdGEsIGFlcyh4PVBJQ3BlcmNlbGxwZywgeT1iZXRhLnByZWQpKSArDQogIGdlb21fcG9pbnQoc2l6ZT01LCBhZXMoY29sb3I9UElDcGVyY2VsbHBnKSkrDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudChuYW1lPSJQSUMiLCBndWlkZT1ndWlkZV9jb2xvcmJhcihkaXJlY3Rpb24gPSAidmVydGljYWwiLCBiYXJoZWlnaHQ9MTApKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKSArIA0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpICsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbihiZXRhfigiUHJlZGljdGVkIEVuY291bnRlcnMifmNtXjN+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMifmNlbGxeLTEpKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikNClBJQ2JldGFfbmV3DQoNCiNiLiBmb3IgbGl0aHMNClBJQ19uZXdkYXRhJHBlcmxpdGhwZy5wcmVkIDwtIHByZWRpY3QocGVybGl0aF9yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGEkU2lua1ZlbC5wcmVkLmxpdGggPC0gcHJlZGljdChzaW5rdmVsX2xpdGhfcmVnLCBkYXRhLmZyYW1lKFBJQ19uZXdkYXRhKSkNCnNpbmt2ZWxfbGl0aF9yZWcucHJlZCA8LSBsbShTaW5rVmVsLnByZWQubGl0aH5QSUNwZXJjZWxscGcsIGRhdGE9UElDX25ld2RhdGEpIA0KY29lZihzaW5rdmVsX2xpdGhfcmVnLnByZWQpDQojc2FtZSBjb2VmIGFzIHNpbmt2ZWxfbGl0aF9yZWcNCiM+IGNvZWYoc2lua3ZlbF9saXRoX3JlZy5wcmVkKQ0KIyhJbnRlcmNlcHQpIFBJQ3BlcmNlbGxwZyANCiMgMC4wMTY3Mjc1MyAgIDAuMDExMTUxNjkgDQoNCnBsb3QocmVzaWQoc2lua3ZlbF9saXRoX3JlZy5wcmVkKSkNCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEsIGFlcyh4PXBlcmxpdGhwZy5wcmVkLCB5PVNpbmtWZWwucHJlZC5saXRoKSkgK2dlb21fcG9pbnQoc2l6ZT0yKSArdGhlbWVfUHVibGljYXRpb24oKSsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbigiUHJlZGljdGVkIFNpbmtpbmcgdmVsb2NpdHkgb2YgTGl0aHMifigibSJ+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMifmxpdGheLTEpKSANCg0KUElDX25ld2RhdGEkYmV0YS5wcmVkLmxpdGggPC0gcHJlZGljdChiZXRhX2xpdGhfcmVnLCBkYXRhLmZyYW1lKFBJQ19uZXdkYXRhKSkNClBJQ19uZXdkYXRhJEVfRFNfVi5wcmVkLmxpdGggPC0gcHJlZGljdChFbGl0aF9EU19IVl9yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KUElDX25ld2RhdGEkRV9EU19IVi5wcmVkLmxpdGggPC0gcHJlZGljdChFbGl0aF9EU19IVl9yZWcsIGRhdGEuZnJhbWUoUElDX25ld2RhdGEpKQ0KDQpnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSwgYWVzKHg9cGVybGl0aHBnLnByZWQsIHk9RV9EU19WLnByZWQubGl0aCkpICtnZW9tX3BvaW50KHNpemU9NSwgYWVzKGNvbG9yPWdyb3VwMikpICsNCiAgdGhlbWVfUHVibGljYXRpb24oKSArIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikrIGdlb21fc21vb3RoKCkNCg0KUElDYmV0YV9uZXcubGl0aCA8LSBnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSwgYWVzKHg9cGVybGl0aHBnLnByZWQsIHk9YmV0YS5wcmVkLmxpdGgpKSArDQogIGdlb21fcG9pbnQoc2l6ZT01LCBhZXMoY29sb3I9UElDcGVyY2VsbHBnKSkrDQogIHNjYWxlX2NvbG91cl9ncmFkaWVudChuYW1lPSJQSUMiLCBndWlkZT1ndWlkZV9jb2xvcmJhcihkaXJlY3Rpb24gPSAidmVydGljYWwiLCBiYXJoZWlnaHQ9MTApKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKSArIA0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpICsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbihiZXRhfigiUHJlZGljdGVkIEVuY291bnRlcnMgb2YgbGl0aCAiIH5jbV4zfmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIn5saXRoXi0xKSkrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpDQpQSUNiZXRhX25ldy5saXRoDQoNCiNzdW1tYXJpZXMNCnN1bW1hcnlfRFNfbmV3ZGF0YV9ieWdyb3VwMiA8LSBkZHBseShQSUNfbmV3ZGF0YSwgLihncm91cDIpLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCBTaW5rVmVsLnByZWQ9bWVhbihTaW5rVmVsLnByZWQpLGJldGEucHJlZD0gbWVhbiAoYmV0YS5wcmVkKSwgRV9EU19WLnByZWQ9IG1lYW4oRV9EU19WLnByZWQpLCBFX0RTX0hWLnByZWQ9bWVhbihFX0RTX0hWLnByZWQpKQ0KDQpzdW1tYXJ5X0RTX2J5Z3JvdXAucHJlZCA8LSBkZHBseShQSUNfbmV3ZGF0YSwgLihncm91cDIpLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJsaXRocGcucHJlZCA9IG1lYW4ocGVybGl0aHBnLnByZWQpLCBTaW5rVmVsLnByZWQ9bWVhbihTaW5rVmVsLnByZWQpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJldGEucHJlZD0gbWVhbiAoYmV0YS5wcmVkKSwgRV9EU19WLnByZWQ9IG1lYW4oRV9EU19WLnByZWQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFX0RTX0hWLnByZWQ9bWVhbihFX0RTX0hWLnByZWQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaW5rVmVsLnByZWQubGl0aD1tZWFuKFNpbmtWZWwucHJlZC5saXRoKSxiZXRhLnByZWQubGl0aD0gbWVhbiAoYmV0YS5wcmVkLmxpdGgpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVfRFNfVi5wcmVkLmxpdGg9IG1lYW4oRV9EU19WLnByZWQubGl0aCksIEVfRFNfSFYucHJlZC5saXRoPW1lYW4oRV9EU19IVi5wcmVkLmxpdGgpKQ0KDQpzdW1tYXJ5X0RTX2J5Z3JvdXAucHJlZA0KDQp3cml0ZS54bHN4KHN1bW1hcnlfRFNfYnlncm91cC5wcmVkLCBmaWxlID0gIlBvc3Rkb2MtUi9FeHBvcnRlZCBUYWJsZXMvc3VtbWFyeV9EU19ieWdyb3VwLnByZWQueGxzeCIpDQoNCg0KYGBgDQoNCnR1cmJ1bGVuY2UNCg0KYGBge3J9DQojVFVSQlVMRU5DRQ0KI2Rpc3JhdGUgaXMgY20yL3MzDQoNCiNtYWtlIGRhdGEgZnJhbWUNCg0KZGlzcmF0ZSA8LSByZXBfbGVuKDEwXigtODotMiksIGxlbmd0aC5vdXQ9MTQpDQpjYWxjIDwtIHJlcF9sZW4oYygiY2FsY2lmaWVkIiksIGxlbmd0aC5vdXQ9NykNCm5ha2VkIDwtIHJlcF9sZW4oYygibmFrZWQiKSwgbGVuZ3RoLm91dD03KQ0KZ3JvdXAgPC0gYyhjYWxjLCBuYWtlZCkNCnR1cmIgPC0gYXMuZGF0YS5mcmFtZShjYmluZChkaXNyYXRlLCBncm91cCkpDQoNCnR1cmIgPC0gbXV0YXRlKHR1cmIsIHJhZCA9IGlmZWxzZShncm91cCA9PSAibmFrZWQiICwgIDEuOEUtNiwgIDIuM0UtNikpICNpbiBtDQoNCnR1cmIkZGlzcmF0ZSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih0dXJiJGRpc3JhdGUpKQ0KDQp0dXJiJEtvbCA8LSAoKHZeMy90dXJiJGRpc3JhdGUpXjAuMjUpKjEwMCAjS29sbW9nb3JvdiBsZW5ndGggc2NhbGUgaW4gY20NCiNldmVyeXRoaW5nIGlzIGJlbG93IDEgY20sIHVzZSBlcW4gMiBpbiBUSyANCg0KdHVyYiRiZXRhX2QgPC0gKDQuMipwaSooKHR1cmIkZGlzcmF0ZS8odioxMDBeMikpXjAuNSkqKCgodHVyYiRyYWQrUmVodikqMTAwKV4zKSkqODY0MDAgDQoNCnR1cmIkYmV0YV9IZWlkaSA8LSAoMC40MipwaSooKHR1cmIkZGlzcmF0ZS8odioxMDBeMikpXjAuNSkqKCgodHVyYiRyYWQrUmVodikqMTAwKV4zKSkqODY0MDANCg0KI2NoZWNrIGVuY291bnRlcnMNCg0KI3VzZSBUSywgaW4gY20zIHMNCnR1cmIkRV90dXJiX0hWIDwtICh0dXJiJGJldGFfZCpob3N0bnVtKnZpcm51bSkgI0UgY2FsY3VsYXRlZCB3aXRoIFZpcnVzIGFuZCBIb3N0ICgxMDoxIE1PSSkNCnR1cmIkRV90dXJiX1YgPC0gKHR1cmIkYmV0YV9kKnZpcm51bSkgI0UgY2FsY3VsYXRlZCB3aXRoIHZpcnVzIG9ubHkNCg0KYnJlYWtzIDwtIDEwXigtMTA6MTApDQptaW5vcl9icmVha3MgPC0gcmVwKDE6OSwgMjEpKigxMF5yZXAoLTEwOjEwLCBlYWNoPTkpKQ0KDQpnZ3Bsb3QoZGF0YSA9IHR1cmIsIGFlcyh4ID0gZGlzcmF0ZSwgeSA9IGJldGFfZCwgY29sb3I9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZSA9NSkgKw0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgc2NhbGVfeF9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3MoKSArDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkNCg0KbGlicmFyeShzY2FsZXMpDQoNCmdncGxvdChkYXRhID0gdHVyYiwgYWVzKHggPSBkaXNyYXRlLCB5ID0gRV90dXJiX1YsIGNvbG9yPWdyb3VwKSkgKyBnZW9tX3BvaW50KHNpemUgPTUpICsNCiAgIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBzY2FsZV94X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgYW5ub3RhdGlvbl9sb2d0aWNrcygpKw0KICB0aGVtZV9QdWJsaWNhdGlvbigpDQoNCmBgYA0KDQphZGQgYmV0YSBrZXJuZWxzIGFuZCBwbG90DQoNCmBgYHtyfQ0KI2V4dHJhY3QgbWVhbiBiZXRhcyBmcm9tIFBJQ19uZXdkYXRhDQpiZXRhX0RTIDwtIHN1bW1hcnlTRSAoUElDX25ld2RhdGEsIG1lYXN1cmV2YXIgPSAiYmV0YS5wcmVkIiwgZ3JvdXB2YXJzID0gYygiZ3JvdXAiLCAiZ3JvdXAyIikpDQoNCmFsbCA8LSBSZWR1Y2UoZnVuY3Rpb24oeCx5KSBtZXJnZSh4LHksYnk9Imdyb3VwIixhbGw9VFJVRSkgLGxpc3QoQk0sIGJldGFfRFMsIHR1cmIpKQ0KI2JldGFfZC54PUJNLCBiZXRhLnByZWQ9RFMsIGJldGFfZC55PXR1cmINCg0KI3JlbmFtZSBiZXRhLnByZWQgdG8gYmV0YV9wcmVkIHNvIEkgY2FuIHVzZSBncmVwLiANCiNhbGwgPC0gcmVuYW1lIChhbGwsIGMoImJldGFfZC54IiA9ICJiZXRhX0JNIiwgImJldGEucHJlZCIgPSAiYmV0YV9EUyIsICJiZXRhX2QueSIgPSAiYmV0YV90dXJiIikpDQoNCmxpYnJhcnkoZGF0YS50YWJsZSkNCk5UID0gZGF0YS50YWJsZShhbGwsIGtleT0iZ3JvdXAyIikNCmFsbGJldGFzID0gTlRbLCBsaXN0KGdyb3VwPWdyb3VwLCBkaXNyYXRlPWRpc3JhdGUsIGJldGFfQk09YmV0YV9kLngsIGJldGFfRFM9YmV0YS5wcmVkLCBiZXRhX3R1cmIgPSBiZXRhX2QueSwgDQogICAgICAgICAgICAgICAgICAgICBiZXRhX0JNX0RTID1iZXRhX2QueCArIGJldGEucHJlZCwNCiAgICAgICAgICAgICAgICAgICAgIGJldGFfRFNfdHVyYiA9IGJldGEucHJlZCArIGJldGFfZC55LA0KICAgICAgICAgICAgICAgICAgICAgYmV0YV9CTV90dXJiID0gYmV0YV9kLnggKyBiZXRhX2QueSwNCiAgICAgICAgICAgICAgICAgICAgIGJldGFfYWxsID0gYmV0YV9kLnggKyBiZXRhX2QueSArIGJldGEucHJlZCksIA0KICAgICAgICAgICAgICBieT1jKCJncm91cDIiKV0NCg0KZ2dwbG90KGFsbGJldGFzLCBhZXMoZGlzcmF0ZSwgeSA9IHZhbHVlLCBjb2xvcj1ncm91cDIpKSArIA0KICBnZW9tX2xpbmUoYWVzKHkgPSBiZXRhX0RTX3R1cmIsIGxpbmV0eXBlID0gIkRTK3R1cmIiKSwgc2l6ZT0xKSArIA0KICBnZW9tX2xpbmUoYWVzKHkgPSBiZXRhX2FsbCwgbGluZXR5cGUgPSAiQk0rRFMrdHVyYiIpLCBzaXplPTEpKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBiZXRhX3R1cmIsIGxpbmV0eXBlID0gInR1cmIiKSwgc2l6ZT0xKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIHNjYWxlX3hfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NyksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBhbm5vdGF0aW9uX2xvZ3RpY2tzKCkrDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkNCg0KI2VuY291bnRlcnMNCg0KI21lbHQgZGF0YQ0KDQphbGxiZXRhcy5tZWx0IDwtIG1lbHQgKGFsbGJldGFzLCBpZC52YXJzID0gYygiZ3JvdXAyIiwgImdyb3VwIiwgImRpc3JhdGUiKSwgdmFsdWUubmFtZSA9ICJiZXRhX2QiLCANCiAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUubmFtZSA9ICJiZXRha2VybmVsIikNCg0KYWxsYmV0YXMubWVsdCRncm91cDIgPC0gZmFjdG9yIChhbGxiZXRhcy5tZWx0JGdyb3VwMixsZXZlbHM9IGMoIm5ha2VkX2JvdXlhbnQiLCAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwgInN0cm9uZ2x5IGNhbGNpZmllZCIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIm5ha2VkIiwgIm5ha2VkL2NhbGNpZmllZCB1bmNlcnRhaW4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwgInN0cm9uZ2x5IGNhbGNpZmllZCIpKQ0KDQphbGxiZXRhcy5tZWx0JEVfViA8LSBhbGxiZXRhcy5tZWx0JGJldGFfZCp2aXJudW0NCg0KZ2dwbG90KGFsbGJldGFzLm1lbHQsIGFlcyhkaXNyYXRlLCB5ID0gRV9WLCBjb2xvcj1ncm91cDIpKSArIA0KICBnZW9tX2xpbmUoc2l6ZT0xKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIHNjYWxlX3hfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NyksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBhbm5vdGF0aW9uX2xvZ3RpY2tzKCkgKyBmYWNldF9ncmlkKH5iZXRha2VybmVsKQ0KDQojc3Vic2V0IGRhdGENCg0KZ3JhcGgxIDwtIHN1YnNldChhbGxiZXRhcy5tZWx0LCBiZXRha2VybmVsICVpbiUgYyAoImJldGFfQk0iLCAiYmV0YV9EUyIsICJiZXRhX0JNX0RTIikpDQpncmFwaDIgPC0gc3Vic2V0KGFsbGJldGFzLm1lbHQsIGJldGFrZXJuZWwgJWluJSBjICgiYmV0YV90dXJiIiwgImJldGFfRFNfdHVyYiIsICJiZXRhX0JNX3R1cmIiLCAiYmV0YV9hbGwiKSkNCg0KZ2dwbG90KGdyYXBoMSwgYWVzKGdyb3VwMiwgeSA9IEVfViwgY29sb3I9YmV0YWtlcm5lbCkpICsgDQogIGdlb21faml0dGVyKHNpemU9NSkrDQogIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NCksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzID0gImwiKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKQ0KDQpncmFwaDEuc3VtIDwtIHN1bW1hcnlTRSAoZ3JhcGgxLCBtZWFzdXJldmFyID0gIkVfViIsIGdyb3VwdmFycyA9IGMoImJldGFrZXJuZWwiLCAiZ3JvdXAyIikpDQoNCmdncGxvdChncmFwaDEuc3VtLCBhZXMoZ3JvdXAyLCB5ID0gRV9WLCBjb2xvcj1iZXRha2VybmVsKSkgKyANCiAgZ2VvbV9wb2ludChzaXplPTUsICBwb3NpdGlvbj1wb3NpdGlvbl9kb2RnZSgwLjIpKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXMgPSAibCIpKw0KICB0aGVtZV9QdWJsaWNhdGlvbigpDQoNCmdncGxvdChkYXRhPWFsbGJldGFzLm1lbHQgJT4lIGZpbHRlcihiZXRha2VybmVsICVpbiUgYygiYmV0YV90dXJiIiwgImJldGFfYWxsIikpLCANCiAgICAgICBhZXMoeD1kaXNyYXRlLHkgPSBFX1YsIGNvbG9yPWdyb3VwMiwgbGluZXR5cGU9YmV0YWtlcm5lbCkpICsgDQogIGdlb21fbGluZShzaXplPTEsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcih3PTAuMDIsIGg9MCkpKw0KICAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIHNjYWxlX3hfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NyksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBhbm5vdGF0aW9uX2xvZ3RpY2tzKCkrDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkNCg0KZ2dwbG90KGRhdGE9YWxsYmV0YXMubWVsdCAlPiUgZmlsdGVyKGJldGFrZXJuZWwgJWluJSBjKCJiZXRhX2FsbCIpKSwgDQogICAgICAgYWVzKHg9ZGlzcmF0ZSx5ID0gRV9WLCBjb2xvcj1ncm91cDIpKSArIA0KICBnZW9tX2xpbmUoc2l6ZT0xLCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIodz0wLjAyLCBoPTApKSsNCiAgIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBzY2FsZV94X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTcpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgYW5ub3RhdGlvbl9sb2d0aWNrcygpKw0KICB0aGVtZV9QdWJsaWNhdGlvbigpDQoNCmBgYA0KDQo=